﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Algorytm;
using ScheduleMaker.ConfigManager;
using ScheduleMaker.Converter;
using ScheduleMaker.DB;

//usingi do DEBUGA
using ScheduleMaker.DB.CoreDAO;
using ScheduleMaker.DB.Domain;
using ScheduleMaker.DB.Domain.Core;

namespace ScheduleMaker
{
    public partial class smAdminForm : Form
    {
        // Userzy
        IList<DB.Domain.Core.User> users;
        // Prowadzący
        IList<DB.Domain.Core.Teacher> teachers;
        // Grupy
        IList<DB.Domain.Core.Group> groups;
        // Przedmioty - zajęcia
        IList<DB.Domain.Core.Subject> subjects;
        // Sale
        IList<DB.Domain.Core.Classroom> classrooms;
        // Wyposażenie
        IList<DB.Domain.Core.Equipment> equipments;

        // Bloki zajęć
        IList<DB.Domain.Core.Category> categories;

        // Godziny zajęć
        IList<DB.Domain.Core.ClassHour> classHours;

        IList<DB.Domain.Core.Day> days;
        IList<TeacherUnavailability> toDeleteTeacherUnavailability;
        IList<ClassroomUnavailability> toDeleteClassroomUnavailability;
        Dictionary<Int32, TeacherInaccessibility> teacherInnaccessibility = new Dictionary<Int32, TeacherInaccessibility>();
        Dictionary<Int32, ClassroomInaccessibility> classroomInaccessibility = new Dictionary<Int32, ClassroomInaccessibility>();

        private DateTime emergencyScheduleWeek;
        private bool boolEmergencyScheduleWeek = false;


        public smAdminForm()
        {
            InitializeComponent();
        }

        private void smAdminForm_Load(object sender, EventArgs e)
        {
            this.getUserList();
            this.getGroupList();
            this.getSubjectList();
            this.getClassroomList();
            this.getEquipmentList();
            this.getTeacherList();

            // Zarządzanie gdozinami
            this.loadHours();
            this.fillClassHours();
            //ładowanie EmergencyScheduleTab
            this.loadEmergencyScheduleTabPage();
            //ładowanie Dni
            this.loadDays();
            
            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
            {
                this.Text = "ScheduleMaker - Panel Administratora - TRYB: SZKOŁA";
                btnGroup4.Visible = false;
                btnGroup5.Visible = false;
            }
            else
            {
                this.Text = "ScheduleMaker - Panel Administratora- TRYB: UCZELNIA";
                lblAdmGenZajGr.Visible = false;
                button19.Visible = false;

                // Zmiana opisów na zakładce
                tabPage3.Text = "Bloki zajęć";
                gbGroup.Text = "Bloki zajęć";
                btnGroup1.Visible = false;
                btnGroup2.Visible = false;
                btnGroup3.Text = "Usuń blok zajęć";
                this.getCategortyList();
            }
        }

        private void loadEmergencyScheduleTabPage()
        {
            // do przeniesienia
            gridTeacherInaccessibility.Rows.Clear();
            gridTeacherInaccessibility.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            gridTeacherInaccessibility.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft;
            gridTeacherInaccessibility.ReadOnly = true;
            gridTeacherInaccessibility.AllowUserToAddRows = false;
            gridTeacherInaccessibility.ColumnCount = 3;
            gridTeacherInaccessibility.Columns[0].Name = "Prowadzący";
            gridTeacherInaccessibility.Columns[0].MinimumWidth = 150;
            gridTeacherInaccessibility.Columns[1].Name = "Od:";
            gridTeacherInaccessibility.Columns[1].MinimumWidth = 150;
            gridTeacherInaccessibility.Columns[2].Name = "Do:";
            gridTeacherInaccessibility.Columns[2].MinimumWidth = 150;
            dtpickFromTeacherInaccessibility.Format = dtpickToTeacherInaccessibility.Format = DateTimePickerFormat.Custom;
            dtpickFromTeacherInaccessibility.CustomFormat = dtpickToTeacherInaccessibility.CustomFormat = "dd-MM-yyyy HH:mm";

            dataGridViewClassroomInaccessibility.Rows.Clear();
            dataGridViewClassroomInaccessibility.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            dataGridViewClassroomInaccessibility.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft;
            dataGridViewClassroomInaccessibility.ReadOnly = true;
            dataGridViewClassroomInaccessibility.AllowUserToAddRows = false;
            dataGridViewClassroomInaccessibility.ColumnCount = 3;
            dataGridViewClassroomInaccessibility.Columns[0].Name = "Sala:";
            dataGridViewClassroomInaccessibility.Columns[0].MinimumWidth = 150;
            dataGridViewClassroomInaccessibility.Columns[1].Name = "Od:";
            dataGridViewClassroomInaccessibility.Columns[1].MinimumWidth = 150;
            dataGridViewClassroomInaccessibility.Columns[2].Name = "Do:";
            dataGridViewClassroomInaccessibility.Columns[2].MinimumWidth = 150;
            dateTimePickerFromClassroomInaccessibility.Format = dateTimePickerToClassroomInaccessibility.Format = DateTimePickerFormat.Custom;
            dateTimePickerFromClassroomInaccessibility.CustomFormat = dateTimePickerToClassroomInaccessibility.CustomFormat = "dd-MM-yyyy HH:mm";
            //

            loadTeachersEmergencyScheduleTabPage();
            loadClassroomsEmergencyScheduleTabPage();
        }

        private void loadTeachersEmergencyScheduleTabPage()
        {
            TeacherDAO teacherDAO = DB.DAOFactory.getTeacherDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            teachers = teacherDAO.getAll();
            foreach (var elem in teachers)
            {
                //comboBoxTeachers.Items.Add(elem.Id + " - " + elem.Name);
                // do przeniesienia
                comboBoxAddTeacherInaccessibility.Items.Add(elem.Id + " - " + elem.Name);
                //
            }
            //combooxTeachers.DropDownStyle = ComboBoxStyle.DropDownList;
            // do przeniesienia
            comboBoxAddTeacherInaccessibility.DropDownStyle = ComboBoxStyle.DropDownList;
            comboBoxAddTeacherInaccessibility.SelectedIndex = 0;
            //
        }
        private void loadClassroomsEmergencyScheduleTabPage()
        {
            DB.CoreDAO.ClassroomDAO classroomDAO = DB.DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            classrooms = classroomDAO.getAll();
            foreach (var elem in classrooms)
            {
                comboBoxAddClassroomInaccessibility.Items.Add(elem.Id + " - " + elem.Name);
            }
            comboBoxAddClassroomInaccessibility.DropDownStyle = ComboBoxStyle.DropDownList;
            comboBoxAddClassroomInaccessibility.SelectedIndex = 0;

        }

        private void fillClassHours()
        {
            //loadHours();
            this.gridClassHour.Rows.Clear();

            foreach (var hour in classHours)
            {
                int n = gridClassHour.Rows.Add();
                gridClassHour.Rows[n].Cells[0].Value = hour.Begin;
                gridClassHour.Rows[n].Cells[1].Value = hour.End;
                gridClassHour.Rows[n].Cells[2].Value = hour.Id;
            }

        }

        private void loadDays()
        {
            DB.CoreDAO.DayDAO dao = DB.DAOFactory.getDayDAO(ConfigManager.ConfigManager.getConfiguration().Type); ;
            days = dao.getAll();
        }
        private void loadHours()
        {
            //grid.RowHeadersWidth = 200;

            DB.CoreDAO.ClassHourDAO dao = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type); ;
            classHours = dao.getAll();
            /*
            int i = 0;
            foreach (var classHour in classHours)
            {
                string[] rowValues = { };
                grid.Rows.Add(rowValues);
                grid.Rows[i++].HeaderCell.Value =
                    classHour.Begin.ToString().Substring(0, 5) +
                    " - " +
                    classHour.End.ToString().Substring(0, 5)
                    ;

            }
             * */
        }
        
        private void wczytajPlanToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void zakończToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Hide();
            this.Close();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
        }

        private void tabPage9_Click(object sender, EventArgs e)
        {
        }

        private void button3_Click(object sender, EventArgs e)
        {
            int selectedIndex = lbUsers.SelectedIndex;

            if (MessageBox.Show("Czy na pewno chcesz usunąć tego użytkownika?", "Potwierdź usunięcie " + selectedIndex, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // coś tam xD - gdy usuwamy
                try
                {
                    if (ConfigManager.ConfigManager.isConfigLoaded())
                    {
                        DB.Domain.Core.User user = users.ElementAt(selectedIndex);
                        UserDAO userDAO = DAOFactory.getUserDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        userDAO.delete(user);
                    }

                    this.getUserList();
                    this.getTeacherList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            smAdmUserAddForm admUserAdd = new smAdmUserAddForm(this);
            admUserAdd.Show();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            int selectedIndex = lbGroup.SelectedIndex;
            // przekazanie obiektu do formy
            try
            {
                DB.Domain.Core.Group group = groups.ElementAt(selectedIndex);

                smAdmGroupEdit admGroupEdit = new smAdmGroupEdit(group);
                admGroupEdit.Show();
            }
            catch
            {
                MessageBox.Show("Nie wybrano grupy!", "Błąd " + selectedIndex);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Czy na pewno chcesz usunąć tego prowadzącego?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                int selectedIndex = lbTeachers.SelectedIndex;
                // coś tam xD - gdy usuwamy
                try
                {
                    // usuwanie z bazy
                    DB.Domain.Core.Teacher teacher = teachers.ElementAt(selectedIndex);
                    TeacherDAO teacherDAO = DAOFactory.getTeacherDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    teacherDAO.delete(teacher);

                    this.getTeacherList();
                    this.getUserList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
            {
                if (MessageBox.Show("Czy na pewno chcesz usunąć tą grupę?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    int selectedIndex = lbGroup.SelectedIndex;
                    // coś tam xD - gdy usuwamy
                    try
                    {
                        // usuwanie z bazy
                        DB.Domain.Core.Group group = groups.ElementAt(selectedIndex);
                        GroupDAO groupDAO = DAOFactory.getGroupDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        groupDAO.delete(group);

                        this.getGroupList();
                    }
                    catch
                    {
                        MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                    }
                }
            }
            else
            {
                if (MessageBox.Show("Czy na pewno chcesz usunąć ten blok?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    int selectedIndex = lbGroup.SelectedIndex;
                    // coś tam xD - gdy usuwamy
                    try
                    {
                        // usuwanie z bazy
                        DB.Domain.Core.Category category = categories.ElementAt(selectedIndex);
                        CategoryDAO categoryDAO = DAOFactory.getCategoryDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        categoryDAO.delete(category);
                        this.getCategortyList();
                    }
                    catch
                    {
                        MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                    }
                }
            }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            smAdmGroupAdd admGroupAdd = new smAdmGroupAdd(this);
            admGroupAdd.Show();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
            {
                smAdmSubjectAddForm admSubAdd = new smAdmSubjectAddForm(this);
                admSubAdd.Show();
            }
            else
            {
                SmAdmSubjectAddUniForm admSubAdd = new SmAdmSubjectAddUniForm(this);
                admSubAdd.Show();
            }
        }

        private void button10_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Czy na pewno chcesz usunąć te zajęcia?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // coś tam xD - gdy usuwamy
                int selectedIndex = lbSubject.SelectedIndex;
                try
                {
                    // usuwanie z bazy
                    DB.Domain.Core.Subject subject = subjects.ElementAt(selectedIndex);
                    SubjectDAO subjectDAO = DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    subjectDAO.delete(subject);

                    this.getSubjectList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            smAdmTeacherAddForm admTeacherAdd = new smAdmTeacherAddForm();
            admTeacherAdd.Show();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Czy na pewno chcesz usunąć wybraną salę?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // coś tam xD - gdy usuwamy
                int selectedIndex = lbClassroom.SelectedIndex;
                try
                {
                    // usuwanie z bazy
                    DB.Domain.Core.Classroom classroom = classrooms.ElementAt(selectedIndex);
                    ClassroomDAO classroomDAO = DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    classroomDAO.delete(classroom);

                    this.getClassroomList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
        }

        private void button14_Click(object sender, EventArgs e)
        {
            smAdmRoomAddForm admRoomAdd = new smAdmRoomAddForm(this);
            admRoomAdd.Show();
        }

        private void button15_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Czy na pewno chcesz usunąć wybrane wyposażenie?", "Potwierdź usunięcie", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // coś tam xD - gdy usuwamy
                int selectedIndex = lbEquipment.SelectedIndex;
                try
                {
                    // usuwanie z bazy
                    DB.Domain.Core.Equipment equipment = equipments.ElementAt(selectedIndex);
                    EquipmentDAO equipmentDAO = DAOFactory.getEquipmentDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    equipmentDAO.delete(equipment);

                    this.getEquipmentList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
        }

        private void button17_Click(object sender, EventArgs e)
        {
            smAdmItemAddForm admItemAdd = new smAdmItemAddForm(this);
            admItemAdd.Show();
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            int selectedIndex = lbSubject.SelectedIndex;
            // przekazanie obiektu do formy
            try
            {
                DB.Domain.Core.Subject subject = subjects.ElementAt(selectedIndex);

                smAdmSubjectEdit admSubjectEdit = new smAdmSubjectEdit(subject);
                admSubjectEdit.Show();
            }
            catch
            {
                int lista = subjects.Count;
                MessageBox.Show("Nie wybrano przedmiotu!", "Błąd " + selectedIndex + " " + lista);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
        }

        private void button13_Click(object sender, EventArgs e)
        {
            int selectedIndex = lbClassroom.SelectedIndex;
            try
            {
                DB.Domain.Core.Classroom classroom = classrooms.ElementAt(selectedIndex);

                // odpalenie formy
                smAdmRoomEditForm admRoomEdit = new smAdmRoomEditForm(classroom);
                admRoomEdit.Show();
            }
            catch
            {
                MessageBox.Show("Nie wybrano sali!", "Błąd " + selectedIndex);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            int selectedIndex = lbTeachers.SelectedIndex;
            try
            {
                DB.Domain.Core.Teacher teacher = teachers.ElementAt(selectedIndex);
                // odpalenie formy
                smAdmTeacherEditForm admTeacherEdit = new smAdmTeacherEditForm(teacher);
                admTeacherEdit.Show();
            }
            catch
            {
                MessageBox.Show("Nie wybrano prowadzącego!", "Błąd " + selectedIndex);
            }
        }

        /**
         *      POBIERANIE DANYCH Z BAZY
         */

        // Pobieranie - użytkowników
        public void getUserList()
        {
            lbUsers.Items.Clear();
            UserDAO userDAO = DAOFactory.getUserDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            //DB.UserDAOSchool userDAO = new DB.UserDAOSchool();
            users = userDAO.getAll();
            foreach (var elem in users)
            {
                lbUsers.Items.Add(elem.Id + ": " + elem.Login);
                //lbUsers.Items.Add("User id: " + elem.Id + " Login: " + elem.Login);
            }
        }

        // Pobieranie - nauczycieli
        public void getTeacherList()
        {
            lbTeachers.Items.Clear();
            TeacherDAO teacherDAO = DAOFactory.getTeacherDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            teachers = teacherDAO.getAll();
            foreach (var elem in teachers)
            {
                lbTeachers.Items.Add(elem.Id + ": " + elem.Name);
                //Console.WriteLine("User id: " + elem.Id + " Login: " + elem.Login);
            }
        }

        // Pobieranie - grup
        public void getGroupList()
        {
            lbGroup.Items.Clear();

            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
            {
                GroupDAO groupDAO = DAOFactory.getGroupDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                groups = groupDAO.getAll();
                foreach (var elem in groups)
                {
                    lbGroup.Items.Add(elem.Id + " grupa: " + elem.Name);
                    //Console.WriteLine("User id: " + elem.Id + " Login: " + elem.Login);
                }
            }
            else
            {
                lbGroup.Items.Add("Na uczelni nie ma grup");
            }
        }

        // Pobieranie - kategori
        public void getCategortyList()
        {
            lbGroup.Items.Clear();

            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.University)
            {
                CategoryDAO categoryDao = DAOFactory.getCategoryDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                categories = categoryDao.getAll();
                foreach (var elem in categories)
                {
                    lbGroup.Items.Add(elem.Id + " blok: " + elem.Name);
                }
            }
            else
            {
                lbGroup.Items.Add("Na uczelni nie ma grup");
            }
        }

        // Pobieranie - przedmiotów
        public void getSubjectList()
        {
            lbSubject.Items.Clear();
            SubjectDAO subjectDAO = DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            subjects = subjectDAO.getAll();
            foreach (var elem in subjects)
            {
                if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
                {
                    lbSubject.Items.Add(elem.Id + ": " + elem.Name);
                }
                else
                {
                    //lbSubject.Items.Add(elem.Id + ": " + elem.Name + " - " + elem.Time + "("+elem.Count+")");
                    lbSubject.Items.Add(elem.Id + ": " + elem.Name + " - " + elem.Time + "h");
                }
                //Console.WriteLine("User id: " + elem.Id + " Login: " + elem.Login);
            }
        }

        // Pobieranie - sale
        public void getClassroomList()
        {
            lbClassroom.Items.Clear();
            ClassroomDAO classroomDAO = DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            classrooms = classroomDAO.getAll();
            foreach (var elem in classrooms)
            {
                lbClassroom.Items.Add(elem.Id + ": " + elem.Name);
                //Console.WriteLine("User id: " + elem.Id + " Login: " + elem.Login);
            }
        }

        // Pobieranie - wyposażenie
        public void getEquipmentList()
        {
            lbEquipment.Items.Clear();
            EquipmentDAO equipmentDAO = DAOFactory.getEquipmentDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            equipments = equipmentDAO.getAll();

            foreach (var elem in equipments)
            {
                lbEquipment.Items.Add(elem.Id + ": " + elem.Name);
                //Console.WriteLine("User id: " + elem.Id + " Login: " + elem.Login);
            }
        }

        private void lbUsers_SelectedIndexChanged(object sender, EventArgs e)
        {
        }

        private void button18_Click(object sender, EventArgs e)
        {
            this.getUserList();
        }

        private void button6_Click_1(object sender, EventArgs e)
        {
            this.getTeacherList();
        }

        private void button18_Click_1(object sender, EventArgs e)
        {
            // Algorytm dla szkoły
            if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
            {
                // Podliczenie wszystkich elementów
                lblAdmGenZajPrz.Text = "Liczba przedmiotów: " + subjects.Count.ToString();
                if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
                {
                    lblAdmGenZajGr.Text = "Liczba grup: " + groups.Count.ToString();
                }
                else
                {
                }
                lblAdmGenTeach.Text = "Liczba prowadzących: " + teachers.Count.ToString();
                lblAdmGenSale.Text = "Liczba sal:" + classrooms.Count.ToString();
                lblAdmGenWyp.Text = "Liczba elementów wyposażenia: " + equipments.Count.ToString();

                Algorytm_Tworzenie_dla_Szkoly alg = new Algorytm_Tworzenie_dla_Szkoly(teachers.Count, subjects.Count, groups.Count, classrooms.Count, 5, 10);


                // Dodanie nauczycieli do algorytmu szkoły
                foreach (var _nauczyciel in teachers)
                {
                    //_nauczyciel.
                    int[] _subjects = new int[_nauczyciel.Subjects.Count];
                    for (int i = 0; i < _nauczyciel.Subjects.Count; i++)
                    {
                        _subjects[i] = _nauczyciel.Subjects.ElementAt(i).Id;
                    }

                    HourDAO hDao = DAOFactory.getHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    IList<DB.Domain.Core.Hour> hours = _nauczyciel.Hours;

                    // przerobienie czasu na godziny kolejnych lekcji
                    ClassHourDAO classHourDAO = DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                    // Zamiana na przedziały
                    IList<Algorytm_Przedzial> _przedzialy = new List<Algorytm_Przedzial>();

                    foreach (var classHour in hours)
                    {
                        IList<Algorytm_Przedzial> _przedzialyGodzinowe = DomainConverter.getAlgorytm_Przedzial(classHour);

                        //_przedzialy.Concat(_przedzialyGodzinowe).ToList();
                        _przedzialy = _przedzialy.Concat<Algorytm_Przedzial>(_przedzialyGodzinowe).ToList<Algorytm_Przedzial>();
                        // DEBUG
                        //Console.WriteLine("nauczyciel: "+_nauczyciel.Id + " - " + classHour.Begin + " - " + classHour.End );
                    }
                    // DEBUG
                    // wyświetlnie przedziałów
                    /*
                    Console.WriteLine("Nauczyciel: " + _nauczyciel.Id + ",przedmiotow: " + _nauczyciel.Subjects.Count + ",przedzialy: " + _przedzialy.Count);
                    foreach (var _p in _przedzialy)
                    {
                        Console.WriteLine("Przedzial - d:" + _p.Dzien + "(" + _p.Poczatek + "," + _p.Koniec + ")");
                    }
                    */
                    alg.dodaj_nauczyciela(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, _subjects, _przedzialy.Count, _przedzialy.ToArray());
                }

                // Dodanie sal do algorytmu szkoły
                foreach (var _sala in classrooms)
                {
                    SubjectDAO subjectDAO = DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    IList<DB.Domain.Core.Subject> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                    //SubjectDAOSchool subjectDAO = new SubjectDAOSchool();
                    //IList<SubjectSchool> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                    int[] _przedmiotyId = new int[_przedmioty.Count];
                    for (int i = 0; i < _przedmioty.Count; i++)
                    {
                        _przedmiotyId[i] = _przedmioty.ElementAt(i).Id;
                    }

                    //IList<DB.Domain.Subject> _przedmioty = subjectDAO.
                    ClassroomDAO classroomDao = DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    //alg.dodaj_sale( id_sali, liczba_przed_w_sali, int[] lista_przedmiotów);
                    //Console.WriteLine(_przedmiotyId.ToString());

                    alg.dodaj_sale(_sala.Id, _przedmioty.Count, _przedmiotyId);

                    // DEBUG
                    /*
                    for (int i = 0; i < _przedmioty.Count; i++)
                    {
                        Console.Write(_przedmiotyId[i] + " ");
                    }
                    Console.WriteLine(" Sala: " + _sala.Id + ", przedmiotow: " + _przedmioty.Count);
                    */
                }

                // Dodanie klas do algorytmu szkoły
                if (ConfigManager.ConfigManager.getConfiguration().Type == Mode.School)
                {
                    foreach (var _grupa in groups)
                    {
                        // liczba przedmiotów
                        //GroupDAOSchool groupDAO = new GroupDAOSchool();
                        GroupDAO groupDAO = DAOFactory.getGroupDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        List<Algorytm_Zajecia> _przedmiotyList = new List<Algorytm_Zajecia>();

                        // różne zajęcia
                        int _amount = 0;
                        //Algorytm_Zajecia[] tab_zaj = new Algorytm_Zajecia[_grupa.SubjectsCount.];

                        // DEBUG
                        Console.WriteLine("Grupa: " + _grupa.Id + ", przedmiotow: " + _grupa.SubjectsCount.Count + " - ");
                        foreach (var _przedmiot in _grupa.SubjectsCount)
                        {
                            _amount += _przedmiot.Value;
                            Algorytm_Zajecia algzaj = new Algorytm_Zajecia(_przedmiot.Key.Id, _przedmiot.Value, 1);
                            _przedmiotyList.Add(algzaj);
                            //DEBUG
                            Console.WriteLine("Zajecia: " + _przedmiot.Key.Id + ", ilosc: (" + _przedmiot.Value + ") ");
                        }
                        //IList<Subject> _przedmioty = _grupa.SubjectsCount.Values;
                        //_przedmiotyList = DomainConverter.getAlgorytm_Zajecia(new List<DB.Domain.Core.Subject>(_grupa.SubjectsCount.Keys));

                        alg.dodaj_klase(_grupa.Id, 0, _grupa.SubjectsCount.Count, _amount, _przedmiotyList.ToArray());

                        //DEBUG
                        /*
                        Console.WriteLine("Grupa: " + _grupa.Id + ", przedmiotow: " + _grupa.SubjectsCount.Count + " - ");
                        foreach (var przed in _przedmiotyList)
                        {
                           // Console.Write( przed.
                        }
                         * */
                    }
                }
                else
                {
                }
                // Testowanie czy wszaystkie dane są poprawne
                Algorytm_Para algPara;
                algPara = alg.Test();

                if (algPara.numer == 1)
                {
                    // Usuwanie starego planu gdy wszystko ok
                    ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    scheduleDAO.deleteAll();
                    // generowanie PLANU

                    alg.start();
                    Algorytm_Wyniki algWyniki = alg.Pobierz_Plan();
                    List<Algorytm_Element_wyniku> wynikiAlg = algWyniki.Pobierz_Liste();

                    foreach (var wynik in wynikiAlg)
                    {
                        Console.WriteLine(wynik.Dzien + " " + wynik.Godzina + " " + wynik.Klasa + " " + wynik.Nauczyciel + " " + wynik.Przedmiot);
                    }

                    Console.WriteLine("ILOSC WYNIKOW *******************************************************************************************" + wynikiAlg.Count);
                    //alg.drukuj_graf(0);

                    ScheduleSchool plan = new ScheduleSchool();

                    //List<Schedule> lista;
                    //IList<ScheduleSchool> scheduleList = new List<ScheduleSchool>();
                    //scheduleList = DomainConverter.getSchedule(wynikiAlg);

                    IList<ScheduleSchool> scheduleList = new List<ScheduleSchool>();
                    List<Schedule> tempList = (List<Schedule>)DomainConverter.getSchedule(wynikiAlg);
                    scheduleList = tempList.ConvertAll(x => (ScheduleSchool)x);

                    //scheduleDAO.save( plan);

                    if (algWyniki.Czy_wygenerowano_pomyslnie())
                    {
                        foreach (var _schedule in scheduleList)
                        {
                            scheduleDAO.saveOrUpdate(_schedule);
                        }
                        MessageBox.Show("Wygenerowano plan!");
                    }
                    else
                    {
                        MessageBox.Show("Plan nie został wygenerowany pomyślnie!");
                    }
                }
                else if (algPara.numer == 0)
                {
                    MessageBox.Show("Za dużo godzin chętnych przez klasy a za mało godzin zadeklarowanych przez prowadzących!", "Błędne dane!");
                }
                else if (algPara.numer == -1)
                {
                    MessageBox.Show("Dla przemdiotu: " + algPara.prio + " jest za mało prowadzących!", "Błędne dane!");
                }
                else if (algPara.numer == -2)
                {
                    MessageBox.Show("Dla przemdiotu: " + algPara.prio + " nie ma sali w której mógłby się odbywać!", "Błędne dane!");
                }
                /*
                //Drukowanie wyników
                alg.drukuj_wierzcholki();
                alg.drukuj_nauczycieli();
                alg.drukuj_graf(1);
                */
            }
            else
            {
                /***************************************************************************************************************************************
                 * ********************************************** UCZELNIA UCZELNIE UCZELNIA ***********************************************************/
                // Algorytm dla uczelni
                //MessageBox.Show("ALgorytm dla uczelni!", "Algorytm dla uczelni");

                // Podliczenie wszystkich elementów
                lblAdmGenZajPrz.Text = "Liczba przedmiotów: " + subjects.Count.ToString();
                lblAdmGenTeach.Text = "Liczba prowadzących: " + teachers.Count.ToString();
                lblAdmGenSale.Text = "Liczba sal:" + classrooms.Count.ToString();
                lblAdmGenWyp.Text = "Liczba elementów wyposażenia: " + equipments.Count.ToString();

                //TODO pododawać wszystko dla algorytmu
                int l_grup_przed = 0;
                foreach (var sub in subjects)
                {
                    l_grup_przed += sub.Count;
                }

                // Liczba przedmiotów które nie mogą odbywać się w tym samym czasie

                Algorytm_Tworzenie_dla_Uczelni algUczelnia = new Algorytm_Tworzenie_dla_Uczelni(teachers.Count, subjects.Count, categories.Count, classrooms.Count, 5, 12);

                /*
                MessageBox.Show("Dane dla algorytmu: \n" +
                    "ilość przedmitów: " + subjects.Count + "\n" +
                    "ilość grup prze: " + l_grup_przed + "\n"
                    , "Algorytm dla uczelni");

                */
                // Dodawanie nauczyciela
                // Dodanie nauczycieli do algorytmu szkoły
                foreach (var _nauczyciel in teachers)
                {
                    // Teraz przedmioty są zappisane gdzieindziej
                    int[] _subjects = new int[_nauczyciel.Subjects.Count];
                    //for (int i = 0; i < _nauczyciel.Subjects.Count; i++)
                    //{
                    //    _subjects[i] = _nauczyciel.Subjects.ElementAt(i).Id;
                    //}
                    for (int i = 0; i < _nauczyciel.SubjectCount.Count; i++)
                    {
                        _subjects[i] = _nauczyciel.SubjectCount.Keys.ElementAt(i).Id;
                    }


                    HourDAO hDao = DAOFactory.getHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    IList<DB.Domain.Core.Hour> hours = _nauczyciel.Hours;
                    // przerobienie czasu na godziny kolejnych lekcji
                    ClassHourDAO classHourDAO = DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    // Zamiana na przedziały
                    //IList<Algorytm_Przedzial> _przedzialy = new List<Algorytm_Przedzial>();

                    IList<Algorytm_Przedzial> _przedzialy = DomainConverter.getAlgorytm_Przedzial2(hours);
                    /*
                    foreach (var classHour in hours)
                    {
                        IList<Algorytm_Przedzial> _przedzialyGodzinowe = DomainConverter.getAlgorytm_Przedzial(classHour);
                        _przedzialy = _przedzialy.Concat<Algorytm_Przedzial>(_przedzialyGodzinowe).ToList<Algorytm_Przedzial>();
                        // DEBUG

                        //Console.WriteLine("nauczyciel: "+_nauczyciel.Id + " - " + classHour.Begin + " - " + classHour.End );
                    }
                     * */
                    // DEBUG
                    // wyświetlnie przedziałów
                    /*
                    Console.WriteLine("Nauczyciel: " + _nauczyciel.Id + ",przedmiotow: " + _nauczyciel.Subjects.Count + ",przedzialy: " + _przedzialy.Count);
                    foreach (var _p in _przedzialy)
                    {
                        Console.WriteLine("Przedzial - d:" + _p.Dzien + "(" + _p.Poczatek + "," + _p.Koniec + ")");
                    }
                    */

                    //Algorytm_Para_Studia algPara = new Algorytm_Para_Studia(
                    List<Algorytm_Para_Studia> prowPrzedmioty = new List<Algorytm_Para_Studia>();
                    //foreach( var sub in _nauczyciel.Subjects) {
                    //    //
                    //    //Algorytm_Para_Studia para = new Algorytm_Para_Studia( sub.Id, sub.Count);
                    //    Algorytm_Para_Studia para = new Algorytm_Para_Studia(sub.Id, 3);
                    //    prowPrzedmioty.Add( para);
                    //}

                    foreach (var sub in _nauczyciel.SubjectCount)
                    {
                        //
                        //Algorytm_Para_Studia para = new Algorytm_Para_Studia( sub.Id, sub.Count);
                        Algorytm_Para_Studia para = new Algorytm_Para_Studia(sub.Key.Id, sub.Value);
                        prowPrzedmioty.Add(para);
                    }

                    Algorytm_Nauczyciel nauczyciel = new Algorytm_Nauczyciel(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, prowPrzedmioty, _przedzialy.Count, _przedzialy.ToArray());

                    algUczelnia.Dodaj_nauczyciela(nauczyciel);
                    //algUczelnia.dodaj_nauczyciela(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, _subjects, _przedzialy.Count, _przedzialy.ToArray());
                }
                // Dodanie sal do algorytmu szkoły
                foreach (var _sala in classrooms)
                {
                    SubjectDAO subjectDAO = DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    IList<DB.Domain.Core.Subject> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                    int[] _przedmiotyId = new int[_przedmioty.Count];
                    for (int i = 0; i < _przedmioty.Count; i++)
                    {
                        _przedmiotyId[i] = _przedmioty.ElementAt(i).Id;
                    }
                    ClassroomDAO classroomDao = DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                    Algorytm_Sala sala = new Algorytm_Sala( _sala.Id, _przedmioty.Count, _przedmiotyId, true);


                    //algUczelnia.dodaj_sale(_sala.Id, _przedmioty.Count, _przedmiotyId);
                    algUczelnia.Dodaj_sale(sala);

                    // DEBUG
                    /*
                    for (int i = 0; i < _przedmioty.Count; i++)
                    {
                        Console.Write(_przedmiotyId[i] + " ");
                    }
                    Console.WriteLine(" Sala: " + _sala.Id + ", przedmiotow: " + _przedmioty.Count);
                    */
                }

                // Dodawanie przedmiotów
                foreach (var przed in subjects)
                {
                    Algorytm_Przedmiot przedmiot = new Algorytm_Przedmiot(przed.Id, przed.Count, przed.Time);
                    algUczelnia.Dodaj_przedmiot(przedmiot);
                    //algUczelnia.Dodaj_przedmiot(
                }

                // Dodanie nadgrup do przedmiotów

                foreach (var cat in categories)
                {
                    /*
                    List<int> idki = new List<int>();
                    foreach (var prze in cat.Subjects)
                    {
                        idki.Add(prze.Id);
                    }
                    */

                    List<Subject> subs = new List<Subject>(cat.Subjects);
                    List<int> idki = subs.ConvertAll<int>(x => x.Id);
                    //int[] _subjects = new int[cat.Subjects.Count];
                    //for (int i = 0; i < cat.Subjects.Count; i++)
                    //{
                    //    //_subjects[i] =
                    //    _subjects[i] = cat.Subjects.ElementAt(i).Id;
                    //}
                    //Algorytm_Grupa_Przedmiotow gr = new Algorytm_Grupa_Przedmiotow(cat.Id, _subjects.ToList);

                    //List<int> idki = ((List<Subject>)cat.Subjects).ConvertAll(x => x.Id);
                    Algorytm_Grupa_Przedmiotow gr = new Algorytm_Grupa_Przedmiotow(cat.Id, idki);

                    algUczelnia.Dodaj_Grupe_Przedmiotow(gr);
                }

                algUczelnia.start();
               // algUczelnia.drukuj_wierzcholki();
               // algUczelnia.drukuj_graf(0);
                Algorytm_Wyniki algWyniki = algUczelnia.Pobierz_Plan();
                List<Algorytm_Element_wyniku> wynikiAlg = algWyniki.Pobierz_Liste();

                /*
                foreach (var wynik in wynikiAlg)
                {
                    Console.WriteLine(wynik.Dzien + " " + wynik.Godzina + " " + wynik.Klasa + " " + wynik.Nauczyciel + " " + wynik.Przedmiot);
                }
                 * */
// Zapisywanie wyników do bazy

                // Usuwanie starego planu gdy wszystko ok
                ScheduleDAO scheduleDAO = DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                scheduleDAO.deleteAll();
                IList<ScheduleUniversity> scheduleList = new List<ScheduleUniversity>();
                List<Schedule> tempList = (List<Schedule>)DomainConverter.getSchedule(wynikiAlg);
                scheduleList = tempList.ConvertAll(x => (ScheduleUniversity)x);

                //scheduleDAO.save( plan)

                if (algWyniki.Czy_wygenerowano_pomyslnie())
                {
                    foreach (var _schedule in scheduleList)
                    {
                        scheduleDAO.saveOrUpdate(_schedule);
                    }
                    MessageBox.Show("Wygenerowano plan!");
                }
                else
                {
                    MessageBox.Show("Plan nie został wygenerowany pomyślnie!");
                }
            }
        }

        private void button16_Click(object sender, EventArgs e)
        {
        }

        private void btnAdmGenGen_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            smScheduleForm scheduleForm = new smScheduleForm();
            scheduleForm.Show();
            Cursor = Cursors.Default;
        }

        private void addNewHour_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            DB.CoreDAO.ClassHourDAO classHourDao = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);

            DB.Domain.Core.ClassHour cHour = null;
            ConfigManager.Config config = ConfigManager.ConfigManager.getConfiguration();
            if (config.Type == ConfigManager.Mode.School)
            {
                cHour = new DB.Domain.ClassHourSchool();
            }
            else
            {
                cHour = new DB.Domain.ClassHourUniversity();
            }

            cHour.Begin = new TimeSpan(Convert.ToInt32(AddNewHourStart.Value), Convert.ToInt32(AddNEwMinuteStart.Value), 0);
            cHour.End = new TimeSpan(Convert.ToInt32(AddNewHourEnd.Value), Convert.ToInt32(AddNewMinuteEnd.Value), 0);
            cHour.Id = Convert.ToInt32(IDnumericUpDown1.Value);
            Boolean hourIsValid = true;
            Boolean hourAlreadyExists = false;
            if (cHour.End <= cHour.Begin)
            {
                hourIsValid = false;
            }

            //validacja godzin
            foreach (var existingHour in classHours)
            {
                if (cHour.Id == existingHour.Id || (existingHour.Begin.Equals(cHour.Begin) && existingHour.End.Equals(cHour.End)))
                {
                    hourAlreadyExists = true;
                    break;
                }
                if (cHour.End <= existingHour.Begin)
                {
                    if (classHours.IndexOf(existingHour) == 0)
                    {
                        //godzina jest ok
                        break;
                    }
                    else if (cHour.Begin < classHours.ElementAt(classHours.IndexOf(existingHour) - 1).End)
                    {
                        hourIsValid = false;
                        break;
                    }
                }
                else if (classHours.IndexOf(existingHour) == classHours.Count - 1 && cHour.Begin < existingHour.End)
                {
                    hourIsValid = false;
                    break;
                }
            }


            if (hourIsValid && !hourAlreadyExists)
            {
                classHourDao.save(cHour);
                MessageBox.Show("Dodano Godzinę.");
            }
            else if (!hourIsValid)
            {
                MessageBox.Show("Nie można dodać takiej godziny!");
            }
            else if (hourAlreadyExists)
            {
                MessageBox.Show("Wybrana Godzina już istnieje!");
            }
            fillClassHours();
            Cursor = Cursors.Default;
        }

        private void button19_Click(object sender, EventArgs e)
        {
            using (smSubjectAndGroups smSandG = new smSubjectAndGroups())
            {
                smSandG.ShowDialog();
            }
        }

        private void button20_Click(object sender, EventArgs e)
        {
            using (smTeachersAndHours smTandH = new smTeachersAndHours())
            {
                smTandH.ShowDialog();
            }
        }

        private void button21_Click(object sender, EventArgs e)
        {
            using (smAdmOvergroupAdd smOverAdd = new smAdmOvergroupAdd(this))
            {
                smOverAdd.ShowDialog();
            }
        }

        private void button22_Click(object sender, EventArgs e)
        {
            //this.getCategortyList();
            int selectedIndex = lbGroup.SelectedIndex;
            try
            {
                DB.Domain.Core.Category category = categories.ElementAt(selectedIndex);

                //if (category == null) MessageBox.Show("Nie wybrano bloku! \n" + selectedIndex + "- jest nullem!", "Błąd ");
                smAdmEditOvergroupSubjects smOverEditfrm = new smAdmEditOvergroupSubjects(category);
                smOverEditfrm.Show();

                /*
                using (smAdmEditOvergroupSubjects smOverEdit = new smAdmEditOvergroupSubjects( category))
                {
                    smOverEdit.ShowDialog();
                }
                 * */
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Nie wybrano bloku!", "Błąd " + selectedIndex);
                MessageBox.Show("Zajec(" + categories.Count + ")\n Nie wybrano bloku!" + ex, "Błąd " + selectedIndex);
            }
        }

        private void button7_Click_1(object sender, EventArgs e)
        {
            
            
            int selectedIndex = lbUsers.SelectedIndex;

            try
            {
                DB.Domain.Core.User user = users.ElementAt(selectedIndex);
                UserDAO userDAO = DAOFactory.getUserDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                smAdmUserAddConfig smAdmConfForm = new smAdmUserAddConfig(user);
                smAdmConfForm.Show();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Nie wybrano użytkownika.", "Błąd " + selectedIndex);
            }


/*
             int selectedIndex = lbUsers.SelectedIndex;

            if (MessageBox.Show("Czy na pewno chcesz usunąć tego użytkownika?", "Potwierdź usunięcie " + selectedIndex, MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                // coś tam xD - gdy usuwamy
                try
                {
 
                    // DEBUG - zmiana na Factory
                    if (ConfigManager.ConfigManager.isConfigLoaded())
                    {
                        DB.Domain.Core.User user = users.ElementAt(selectedIndex);
                        UserDAO userDAO = DAOFactory.getUserDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        userDAO.delete(user);
                    }

                    this.getUserList();
                    this.getTeacherList();
                }
                catch
                {
                    MessageBox.Show("Wystąpił błąd podczas usuwania.", "Błąd " + selectedIndex);
                }
            }
 */
        }

        private void button16_Click_1(object sender, EventArgs e)
        {
            Int32 selectedRowCount = gridClassHour.Rows.GetRowCount(DataGridViewElementStates.Selected);
            if (selectedRowCount > 0)
            {
                int selectedIndex = gridClassHour.SelectedRows[0].Index;
                DB.Domain.Core.ClassHour cHour = classHours.ElementAt(selectedIndex);
                DB.Domain.Core.ClassHour pHour = null;
                if (selectedIndex > 0)
                {
                    pHour = classHours.ElementAt(selectedIndex - 1);
                }
                DB.Domain.Core.ClassHour nHour = null;
                if (selectedIndex + 1 < classHours.Count)
                {
                    nHour = classHours.ElementAt(selectedIndex + 1);
                }
                using (smAdmHourEdit smadmHourEdit = new smAdmHourEdit(cHour, pHour, nHour))
                {
                    smadmHourEdit.ShowDialog();
                }
                fillClassHours();
            }
            else
            {
                MessageBox.Show("Proszę zaznaczyć wiersz z godziną do edycji!");
            }
            Cursor = Cursors.Default;
        }

        private void button8_Click_1(object sender, EventArgs e)
        {
            //smAdmUserAddForm admUserAdd = new smAdmUserAddForm(this);
            //admUserAdd.Show();
            
        }

        private void deleteHour_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            Int32 selectedRowCount = gridClassHour.Rows.GetRowCount(DataGridViewElementStates.Selected);
            if (selectedRowCount > 0)
            {
                int selectedIndex = gridClassHour.SelectedRows[0].Index;
                DB.Domain.Core.ClassHour cHour = classHours.ElementAt(selectedIndex);

                DB.CoreDAO.ClassHourDAO classHourDao = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                classHourDao.delete(cHour);
                MessageBox.Show("Usunięto Godzinę!.");
                fillClassHours();
            }
            else
            {
                MessageBox.Show("Proszę zaznaczyć wiersz z godziną do usunięcia.");
            }
            Cursor = Cursors.Default;
        }

        private void butShowEmergencySchedule_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            smEmergencyScheduleForm emergencyScheduleForm = new smEmergencyScheduleForm();
            emergencyScheduleForm.Show();
            Cursor = Cursors.Default;
        }

        private void buttonClearInaccessibility_Click(object sender, EventArgs e)
        {
            this.clearInaccessibilityData();
        }

        private void buttonAddTeacherInaccessibility_Click(object sender, EventArgs e)
        {
            String comboBox = comboBoxAddTeacherInaccessibility.SelectedItem.ToString();
            foreach (var t in teachers)
            {
                if (comboBox.Equals(t.Id + " - " + t.Name))
                {
                    //DB.Domain.Core.Day day = getDayID(dtpickFromTeacherInaccessibility.Value);
                    //emergencyScheduleWeek is null
                    if (this.boolEmergencyScheduleWeek == false)
                    {
                        MessageBox.Show("Wybierz tydzien!");
                    }
                    else
                    {
                        this.addNewTeacherInaccessibilityRow(t, comboBox);
                    }
                }
            }
        }

        private DB.Domain.Core.Day getDayID(DateTime dateTime)
        {
            string day = "";
            if (dateTime.DayOfWeek == DayOfWeek.Monday)
            {
                day = "Poniedzialek";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Friday)
            {
                day = "Piatek";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Saturday)
            {
                day = "Sobota";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Sunday)
            {
                day = "Niedziela";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Thursday)
            {
                day = "Czwartek";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Tuesday)
            {
                day = "Wtorek";
            }
            else if (dateTime.DayOfWeek == DayOfWeek.Wednesday)
            {
                day = "Sroda";
            }
            foreach (var d in days)
            {
                if (d.Name.Equals(day))
                {
                    Console.WriteLine("getDayID " + d.Name);
                    return d;
                }
            }
            return null;
        }

        private Boolean checkNewClassroomInaccessibility(Classroom classroom_p, DateTime start_p, DateTime end_p)
        {
            foreach (var x in classroomInaccessibility)
            {
                if (x.Value.classroom.Id == classroom_p.Id)
                {
                    if ((start_p >= x.Value.from && start_p <= x.Value.to) || (x.Value.from >= start_p && x.Value.from <= end_p))
                    {
                        MessageBox.Show("Nie można dodać wartości. Zawieranie się przedziałów dla klasy: " + x.Value.classroom.Name + " od: " + x.Value.from + "; do: " + x.Value.to);
                        return false;
                    }
                }
            }
            return true;
        }

        private Boolean checkNewTeacherInaccessibility(Teacher teacher_p, DateTime start_p, DateTime end_p) {
            foreach (var x in teacherInnaccessibility) {
                if (x.Value.teacher.Id == teacher_p.Id) {
                    if ((start_p >= x.Value.from && start_p <= x.Value.to) || (x.Value.from >= start_p && x.Value.from <= end_p)) {
                        MessageBox.Show("Nie można dodać wartości. Zawieranie się przedziałów dla nauczyciela: " + x.Value.teacher.Name + " od: " + x.Value.from + "; do: " + x.Value.to);
                        return false;
                    }
                }
            }
            return true;
        }
        private void addTeacherInnaccessibilityToGrid(TeacherInaccessibility ti)
        {
                    int n = gridTeacherInaccessibility.Rows.Add();
                    gridTeacherInaccessibility.Rows[n].Cells[0].Value = ti.comboBox;
                    gridTeacherInaccessibility.Rows[n].Cells[1].Value = ti.from.ToString("dd-MM-yyyy HH:mm");
                    gridTeacherInaccessibility.Rows[n].Cells[2].Value = ti.to.ToString("dd-MM-yyyy HH:mm");

                    String gridString = gridTeacherInaccessibility.Rows[n].Cells[0].Value.ToString()
                        + gridTeacherInaccessibility.Rows[n].Cells[1].Value.ToString()
                        +gridTeacherInaccessibility.Rows[n].Cells[2].Value.ToString();
                    ti.setRepresentativeGridString(gridString);
                    gridTeacherInaccessibility.AutoResizeColumns();
                    teacherInnaccessibility.Add(n, ti);
                    gridTeacherInaccessibility.AutoResizeRows();
        }

        private void addClassroomInnaccessibilityToGrid(ClassroomInaccessibility ci)
        {
            int n = dataGridViewClassroomInaccessibility.Rows.Add();
            dataGridViewClassroomInaccessibility.Rows[n].Cells[0].Value = ci.comboBox;
            dataGridViewClassroomInaccessibility.Rows[n].Cells[1].Value = ci.from.ToString("dd-MM-yyyy HH:mm");
            dataGridViewClassroomInaccessibility.Rows[n].Cells[2].Value = ci.to.ToString("dd-MM-yyyy HH:mm");

            String gridString = dataGridViewClassroomInaccessibility.Rows[n].Cells[0].Value.ToString()
                + dataGridViewClassroomInaccessibility.Rows[n].Cells[1].Value.ToString()
                + dataGridViewClassroomInaccessibility.Rows[n].Cells[2].Value.ToString();
            ci.setRepresentativeGridString(gridString);

            dataGridViewClassroomInaccessibility.AutoResizeColumns();
            classroomInaccessibility.Add(n, ci);
            dataGridViewClassroomInaccessibility.AutoResizeRows();
        }

        private void addNewTeacherInaccessibilityRow(Teacher t, string comboBox)
        {
            //check if (this.emergencyScheduleWeek.DayOfYear / 7 == dtpickFromTeacherInaccessibility.Value.DayOfYear / 7)//
            DateTime start = dtpickFromTeacherInaccessibility.Value;
            DateTime end = dtpickToTeacherInaccessibility.Value;

            DB.Domain.Core.Day day = getDayID(start);
            if (
                //dataPoczatkowa < dataKoncowa
                start < end &&
                //dzien dataPoczatkowa jest dniem odbywajacych sie zajec
                day != null &&
                //dataPoczatkowa && dataKoncowa sa w tym samym tygodniu
                theSameWeek(start, end) &&
                //dataPoczatkaa && pierwsza_data sa w tym samym tygodniu
                theSameWeek(start, this.emergencyScheduleWeek)
                )
            {
                if (checkNewTeacherInaccessibility(t,start,end))
                {
                    //setujemy emergencyScheduleWeek
                    if (start.DayOfYear != end.DayOfYear)
                    {
                        //dodanie pierwszego dnia
                        DateTime firstDayStart = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                        DateTime firstDayEnd = new DateTime(start.Year, start.Month, start.Day, 23, 59, 59);
                        TeacherInaccessibility ti = new TeacherInaccessibility(t, start, firstDayEnd, day, comboBox);
                        addTeacherInnaccessibilityToGrid(ti);
                        Console.WriteLine("newTI: " + ti.from.ToString() + "-" + ti.to.ToString() + "; Day:" + ti.day.Name + "; Teacher:" + ti.teacher.Name);

                        //petla
                        int difference = end.DayOfYear - start.DayOfYear;
                        for (int i = 1; i <= difference; i++)
                        {
                            //DateTime nextDayStart = new DateTime(start.Year, start.Month, start.Day + i, 0, 0, 0);
                            DateTime nextDayStart = new DateTime(firstDayStart.Ticks + i * TimeSpan.TicksPerDay);
                            DB.Domain.Core.Day nextDayDAO = getDayID(nextDayStart);
                            if (i == difference && nextDayDAO != null)
                            {
                                TeacherInaccessibility teacherI = new TeacherInaccessibility(t, nextDayStart, end, nextDayDAO, comboBox);
                                addTeacherInnaccessibilityToGrid(teacherI);
                                Console.WriteLine("newTI: " + teacherI.from.ToString() + "-" + teacherI.to.ToString() + "; Day:" + teacherI.day.Name + "; Teacher:" + teacherI.teacher.Name);
                            }
                            else if (nextDayDAO != null)
                            {
                                //DateTime nextDayEnd = new DateTime(start.Year, start.Month, start.Day + i, 23, 59, 59);
                                DateTime nextDayEnd = new DateTime(firstDayEnd.Ticks + i * TimeSpan.TicksPerDay);
                                TeacherInaccessibility teacherI = new TeacherInaccessibility(t, nextDayStart, nextDayEnd, nextDayDAO, comboBox);
                                addTeacherInnaccessibilityToGrid(teacherI);
                                Console.WriteLine("newTI: " + teacherI.from.ToString() + "-" + teacherI.to.ToString() + "; Day:" + teacherI.day.Name + "; Teacher:" + teacherI.teacher.Name);
                            }

                        }
                    }
                    else
                    {
                        TeacherInaccessibility ti = new TeacherInaccessibility(t, dtpickFromTeacherInaccessibility.Value, dtpickToTeacherInaccessibility.Value, day, comboBox);
                        addTeacherInnaccessibilityToGrid(ti);
                        Console.WriteLine("ELSE newTI: " + ti.from.ToString() + "-" + ti.to.ToString() + "; Day:" + ti.day.Name + "; Teacher:" + ti.teacher.Name);
                    }
                }

            }
            else
            {
                MessageBox.Show("Prosze wybrac daty z tygodnia: " + getWeekStartEndString() + " lub wyczyscic wprowadzone niedostepnosci!");
            }
        }
        public String getWeekStartEndString()
        {
            DateTime dt = this.emergencyScheduleWeek;
            int startOfWeek = dayOfWeekToInt(dt.DayOfWeek);
            long ticksInSecond = TimeSpan.FromSeconds(1).Ticks;
            long ticksInDay = TimeSpan.FromDays(1).Ticks;
            int dayStart = dayOfWeekToInt(dt.DayOfWeek);
            long startTicks = dt.Ticks - dayStart * ticksInDay - dt.Second * ticksInSecond - dt.Minute * 60 * ticksInSecond - dt.Hour * 3600 * ticksInSecond;
            DateTime weekStart = new DateTime(startTicks);
            DateTime weekEnd = new DateTime(startTicks + 7 * ticksInDay - ticksInSecond);
            String st = weekStart.ToString() + " - " + weekEnd.ToString();
            return st;

        }

        int dayOfWeekToInt(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Monday)
            {
                return 0;
            }
            else if (dayOfWeek == DayOfWeek.Tuesday)
            {
                return 1;
            }
            else if (dayOfWeek == DayOfWeek.Wednesday)
            {
                return 2;
            }
            else if (dayOfWeek == DayOfWeek.Thursday)
            {
                return 3;
            }
            else if (dayOfWeek == DayOfWeek.Friday)
            {
                return 4;
            }
            else if (dayOfWeek == DayOfWeek.Saturday)
            {
                return 5;
            }
            else if (dayOfWeek == DayOfWeek.Sunday)
            {
                return 6;
            }
            throw new Exception("WTF? Exception");
        }

        bool theSameWeek(DateTime first, DateTime second)
        {

            if (first > second)
            {
                DateTime temp = first;
                first = second;
                second = temp;
            }

            int dayOfWeek = this.dayOfWeekToInt(first.DayOfWeek);
            int daySubstraction = second.DayOfYear - (first.DayOfYear - dayOfWeek);
            if (daySubstraction < 7 && daySubstraction >= 0)
            {
                Console.WriteLine("theSameWeek True: " + first.ToString() + "-" + second.ToString());
                return true;
            }
            return false;
        }


        private void addNewClassroomInaccessibilityRow(Classroom c, string comboBox)
        {
            DateTime start = dateTimePickerFromClassroomInaccessibility.Value;
            DateTime end = dateTimePickerToClassroomInaccessibility.Value;

            DB.Domain.Core.Day day = getDayID(start);
            if (
                //dataPoczatkowa < dataKoncowa
                start < end &&
                //dzien dataPoczatkowa jest dniem odbywajacych sie zajec
                day != null &&
                //dataPoczatkowa && dataKoncowa sa w tym samym tygodniu
                theSameWeek(start, end) &&
                //dataPoczatkaa && pierwsza_data sa w tym samym tygodniu
                theSameWeek(start, this.emergencyScheduleWeek)
                )
            {
                if (checkNewClassroomInaccessibility(c,start,end))
                {
                    //setujemy emergencyScheduleWeek
                    if (start.DayOfYear != end.DayOfYear)
                    {

                        //dodanie pierwszego dnia
                        DateTime firstDayStart = new DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                        DateTime firstDayEnd = new DateTime(start.Year, start.Month, start.Day, 23, 59, 59);
                        ClassroomInaccessibility ci = new ClassroomInaccessibility(c, start, firstDayEnd, day, comboBox);
                        addClassroomInnaccessibilityToGrid(ci);
                        Console.WriteLine("newCI: " + ci.from.ToString() + "-" + ci.to.ToString() + "; Day:" + ci.day.Name + "; Classroom:" + ci.classroom.Name);

                        //petla
                        int difference = end.DayOfYear - start.DayOfYear;
                        for (int i = 1; i <= difference; i++)
                        {
                            DateTime nextDayStart = new DateTime(firstDayStart.Ticks + i * TimeSpan.TicksPerDay);
                            //DateTime nextDayStart = new DateTime(start.Year, start.Month, start.Day + i, 0, 0, 0);
                            DB.Domain.Core.Day nextDayDAO = getDayID(nextDayStart);
                            if (i == difference && nextDayDAO != null)
                            {
                                ClassroomInaccessibility classroomI = new ClassroomInaccessibility(c, nextDayStart, end, nextDayDAO, comboBox);
                                addClassroomInnaccessibilityToGrid(ci);
                                Console.WriteLine("newCI: " + classroomI.from.ToString() + "-" + classroomI.to.ToString() + "; Day:" + classroomI.day.Name + "; Classroom:" + classroomI.classroom.Name);
                            }
                            else if (nextDayDAO != null)
                            {
                                DateTime nextDayEnd = new DateTime(firstDayEnd.Ticks + i * TimeSpan.TicksPerDay);
                                //DateTime nextDayEnd = new DateTime(start.Year, start.Month, start.Day + i, 23, 59, 59);
                                ClassroomInaccessibility classroomI = new ClassroomInaccessibility(c, nextDayStart, nextDayEnd, nextDayDAO, comboBox);
                                addClassroomInnaccessibilityToGrid(ci);
                                Console.WriteLine("newCI: " + classroomI.from.ToString() + "-" + classroomI.to.ToString() + "; Day:" + classroomI.day.Name + "; Classroom:" + classroomI.classroom.Name);
                            }

                        }
                    }
                    else
                    {
                        ClassroomInaccessibility ci = new ClassroomInaccessibility(c, start, end, day, comboBox);
                        addClassroomInnaccessibilityToGrid(ci);
                        Console.WriteLine("ELSE newCI: " + ci.from.ToString() + "-" + ci.to.ToString() + "; Day:" + ci.day.Name + "; Classroom:" + ci.classroom.Name);
                    }
                }

            }
            else
            {
                MessageBox.Show("Prosze wybrac daty z tygodnia: " + getWeekStartEndString() + " lub wyczyscic wprowadzone niedostepnosci!");
            }
        }

        private void buttonAddClassroomInaccessibility_Click(object sender, EventArgs e)
        {
            String comboBox = comboBoxAddClassroomInaccessibility.SelectedItem.ToString();
            foreach (var c in classrooms)
            {
                if (comboBox.Equals(c.Id + " - " + c.Name))
                {
                    if (this.boolEmergencyScheduleWeek == false)
                    {
                        MessageBox.Show("Wybierz tydzien!");
                    }
                    else
                    {
                        this.addNewClassroomInaccessibilityRow(c, comboBox);
                    }
                }
            }
        }

        private void buttonEmergencySchedule_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            this.buttonAddClassroomInaccessibility.Enabled = false;
            this.buttonAddTeacherInaccessibility.Enabled = false;
            this.buttonClearInaccessibility.Enabled = false;
            this.buttonEmergencySchedule.Enabled = false;
            bool generate = true;
            bool ifExist = !(this.checkTeachersUnavailability() && this.checkClassroomsUnavailability());
            if(ifExist){
                DialogResult result1 = MessageBox.Show("Plan Awaryjny dla tygodnia " + getWeekStartEndString() + " juz istnieje! Czy chcesz wygenerować nowy?",
            "Informacja",MessageBoxButtons.YesNo);
                if (DialogResult.No == result1) {
                    generate = false;
                }
            }

            // Algorytm dla szkoły
            if (generate)
            {
                if (ConfigManager.ConfigManager.getConfiguration().Type == ConfigManager.Mode.School)
                {
                    Algorytm.Algorytm_Tworzenie_dla_Szkoly alg = new Algorytm.Algorytm_Tworzenie_dla_Szkoly(teachers.Count, subjects.Count, groups.Count, classrooms.Count, 5, 10);

                    // Dodanie nauczycieli do algorytmu szkoły
                    foreach (var _nauczyciel in teachers)
                    {
                        //_nauczyciel.
                        int[] _subjects = new int[_nauczyciel.Subjects.Count];
                        for (int i = 0; i < _nauczyciel.Subjects.Count; i++)
                        {
                            //_subjects[i] =
                            _subjects[i] = _nauczyciel.Subjects.ElementAt(i).Id;
                        }

                        HourDAO hDao = DB.DAOFactory.getHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                        IList<DB.Domain.Core.Hour> hours = _nauczyciel.Hours;
                        // przerobienie czasu na godziny kolejnych lekcji
                        ClassHourDAO classHourDAO = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                        // Zamiana na przedziały
                        IList<Algorytm.Algorytm_Przedzial> _przedzialy = new List<Algorytm.Algorytm_Przedzial>();

                        foreach (var classHour in hours)
                        {
                            IList<Algorytm.Algorytm_Przedzial> _przedzialyGodzinowe = Converter.DomainConverter.getAlgorytm_Przedzial(classHour);

                            //_przedzialy.Concat(_przedzialyGodzinowe).ToList();
                            _przedzialy = _przedzialy.Concat<Algorytm.Algorytm_Przedzial>(_przedzialyGodzinowe).ToList<Algorytm.Algorytm_Przedzial>();
                            // DEBUG
                            //Console.WriteLine("nauczyciel: "+_nauczyciel.Id + " - " + classHour.Begin + " - " + classHour.End );
                        }
                        // DEBUG
                        // wyświetlnie przedziałów

                        Console.WriteLine("Nauczyciel: " + _nauczyciel.Id + ",przedmiotow: " + _nauczyciel.Subjects.Count + ",przedzialy: " + _przedzialy.Count);
                        foreach (var _p in _przedzialy)
                        {
                            Console.WriteLine("Przedzial - d:" + _p.Dzien + "(" + _p.Poczatek + "," + _p.Koniec + ")");
                        }

                        alg.dodaj_nauczyciela(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, _subjects, _przedzialy.Count, _przedzialy.ToArray());
                    }

                    // Dodanie sal do algorytmu szkoły
                    foreach (var _sala in classrooms)
                    {
                        SubjectDAO subjectDAO = DB.DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        IList<DB.Domain.Core.Subject> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                        //SubjectDAOSchool subjectDAO = new SubjectDAOSchool();
                        //IList<SubjectSchool> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                        int[] _przedmiotyId = new int[_przedmioty.Count];
                        for (int i = 0; i < _przedmioty.Count; i++)
                        {
                            _przedmiotyId[i] = _przedmioty.ElementAt(i).Id;
                        }

                        //IList<DB.Domain.Subject> _przedmioty = subjectDAO.
                        ClassroomDAO classroomDao = DB.DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        //alg.dodaj_sale( id_sali, liczba_przed_w_sali, int[] lista_przedmiotów);
                        //Console.WriteLine(_przedmiotyId.ToString());

                        alg.dodaj_sale(_sala.Id, _przedmioty.Count, _przedmiotyId);

                        // DEBUG
                        /*
                        for (int i = 0; i < _przedmioty.Count; i++)
                        {
                            Console.Write(_przedmiotyId[i] + " ");
                        }
                        Console.WriteLine(" Sala: " + _sala.Id + ", przedmiotow: " + _przedmioty.Count);
                        */
                    }

                    // Dodanie klas do algorytmu szkoły
                    if (ConfigManager.ConfigManager.getConfiguration().Type == ConfigManager.Mode.School)
                    {
                        foreach (var _grupa in groups)
                        {
                            // liczba przedmiotów
                            //GroupDAOSchool groupDAO = new GroupDAOSchool();
                            GroupDAO groupDAO = DB.DAOFactory.getGroupDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                            List<Algorytm.Algorytm_Zajecia> _przedmiotyList = new List<Algorytm.Algorytm_Zajecia>();

                            // różne zajęcia
                            int _amount = 0;
                            //Algorytm_Zajecia[] tab_zaj = new Algorytm_Zajecia[_grupa.SubjectsCount.];

                            // DEBUG
                            Console.WriteLine("Grupa: " + _grupa.Id + ", przedmiotow: " + _grupa.SubjectsCount.Count + " - ");
                            foreach (var _przedmiot in _grupa.SubjectsCount)
                            {
                                _amount += _przedmiot.Value;
                                Algorytm.Algorytm_Zajecia algzaj = new Algorytm.Algorytm_Zajecia(_przedmiot.Key.Id, _przedmiot.Value, 1);
                                _przedmiotyList.Add(algzaj);
                                //DEBUG
                                Console.WriteLine("Zajecia: " + _przedmiot.Key.Id + ", ilosc: (" + _przedmiot.Value + ") ");
                            }
                            //IList<Subject> _przedmioty = _grupa.SubjectsCount.Values;
                            //_przedmiotyList = DomainConverter.getAlgorytm_Zajecia(new List<DB.Domain.Core.Subject>(_grupa.SubjectsCount.Keys));

                            alg.dodaj_klase(_grupa.Id, 0, _grupa.SubjectsCount.Count, _amount, _przedmiotyList.ToArray());

                            //DEBUG
                            /*
                            Console.WriteLine("Grupa: " + _grupa.Id + ", przedmiotow: " + _grupa.SubjectsCount.Count + " - ");
                            foreach (var przed in _przedmiotyList)
                            {
                               // Console.Write( przed.
                            }
                             * */
                        }
                    }

                    // Testowanie czy wszaystkie dane są poprawne

                    //start:karmimy starym planem
                    ScheduleDAO scheduleDAO = DB.DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    ClassHourDAO classHourDAO2 = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    scheduleDAO.getAll();

                    List<Algorytm.Algorytm_Element_wyniku> algorytm_element_wyniku = Converter.DomainConverter.getAlgorytmElementWyniku(scheduleDAO.getAll());
                    alg.Ustaw_obecny_plan(algorytm_element_wyniku);
                    //end:karmimy starym planem

                    //start:karmimy niedostepnoscia nauczyciela
                    foreach (var t in teacherInnaccessibility)
                    {
                        Algorytm.Algorytm_Przedzial algorytm_przedzial = new Algorytm.Algorytm_Przedzial();
                        TimeSpan begin = new TimeSpan(t.Value.from.Hour, t.Value.from.Minute, t.Value.from.Millisecond);
                        TimeSpan end = new TimeSpan(t.Value.to.Hour, t.Value.to.Minute, t.Value.to.Millisecond);
                        DB.Domain.HourSchool hour = new DB.Domain.HourSchool();
                        hour.Day = t.Value.day;
                        hour.Begin = begin;
                        hour.End = end;
                        IList<Algorytm.Algorytm_Przedzial> algorytmPrzedzialList = Converter.DomainConverter.getAlgorytm_Przedzial(hour);
                        foreach (var a in algorytmPrzedzialList)
                        {
                            alg.dodaj_nieobecnosc_nauczyciela(t.Value.teacher.Id, a);
                        }
                    }
                    //end:karmimy niedostepnoscia nauczyciela

                    //start:karmimy niedostepnoscia sal
                    foreach (var cr in classroomInaccessibility)
                    {
                        Algorytm.Algorytm_Przedzial algorytm_przedzial = new Algorytm.Algorytm_Przedzial();
                        TimeSpan begin = new TimeSpan(cr.Value.from.Hour, cr.Value.from.Minute, cr.Value.from.Millisecond);
                        TimeSpan end = new TimeSpan(cr.Value.to.Hour, cr.Value.to.Minute, cr.Value.to.Millisecond);
                        DB.Domain.HourSchool hour = new DB.Domain.HourSchool();
                        hour.Day = cr.Value.day;
                        hour.Begin = begin;
                        hour.End = end;
                        IList<Algorytm.Algorytm_Przedzial> algorytmPrzedzialList = Converter.DomainConverter.getAlgorytm_Przedzial(hour);
                        foreach (var a in algorytmPrzedzialList)
                        {
                            Console.WriteLine("classroom: "+cr.Value.classroom.Id+" dzien: "+a.Dzien+" poczatek: "+a.Poczatek+" koniec: "+a.Koniec );
                            alg.dodaj_niedostepnosc_sali(cr.Value.classroom.Id, a);
                        }
                    }
                    //end:karmimy niedostepnoscia nauczyciela


                    // Usuwanie starego planu gdy wszystko ok
                    //ScheduleDAO scheduleDAO = DB.DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    //scheduleDAO.deleteAll();
                    // generowanie PLANU

                    alg.Generuj_plan_awaryjny();
                    Algorytm.Algorytm_Wyniki algWyniki = alg.Pobierz_Plan();
                    List<Algorytm.Algorytm_Element_wyniku> wynikiAlg = algWyniki.Pobierz_Plan_Awaryjny();

                    Console.WriteLine("ILOSC WYNIKOW START*******************************************************************************************" + wynikiAlg.Count);
                    foreach (var wynik in wynikiAlg)
                    {
                        Console.WriteLine(wynik.Dzien + " " + wynik.Godzina + " " + wynik.Klasa + " " + wynik.Nauczyciel + " " + wynik.Przedmiot);
                    }

                    Console.WriteLine("ILOSC WYNIKOW END*******************************************************************************************" + wynikiAlg.Count);
                    //alg.drukuj_graf(0);

                    DB.Domain.ScheduleSchool plan = new DB.Domain.ScheduleSchool();

                    if (algWyniki.Czy_wszystko_poszlo_dobrze)
                    {
                        //usuwamy stary plan
                        deleteOldEmergencySchedule();
                        IList<EmergencySchedule> emergencySchedule = Converter.DomainConverter.getEmergencySchedule(wynikiAlg, this.emergencyScheduleWeek);
                        EmergencyScheduleDAO emergencyScheduleDAO = DB.DAOFactory.getEmergencyScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                        //save teacherInnaccessibility
                        TeacherUnavailabilityDAO teachersUnavailabilityDAO = DB.DAOFactory.getTeacherUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        foreach (var ti in teacherInnaccessibility)
                        {
                            DB.Domain.Core.TeacherUnavailability tiObject = ti.Value.getTeacherUnavailabilityObject();
                            teachersUnavailabilityDAO.saveOrUpdate(tiObject);
                        }
                        //save classroomInaccessibility
                        ClassroomUnavailabilityDAO classroomsUnavailabilityDAO = DB.DAOFactory.getClassroomUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        foreach (var ci in classroomInaccessibility)
                        {
                          DB.Domain.Core.ClassroomUnavailability ciObject = ci.Value.getClassroomUnavailabilityObject();
                                classroomsUnavailabilityDAO.saveOrUpdate(ciObject);
                        }
                        //save emergencySchedule
                        foreach (var es in emergencySchedule)
                        {
                            emergencyScheduleDAO.saveOrUpdate(es);
                        }

                        MessageBox.Show("Wygenerowano plan!");
                    }
                    else
                    {
                        MessageBox.Show("Plan nie został wygenerowany pomyślnie!");
                    }

                    //Drukowanie wyników
                    //alg.drukuj_wierzcholki();
                    //alg.drukuj_nauczycieli();
                    //alg.drukuj_graf(1);

                }
                ////////////////////////////////////////////////////////////////////////////////////////////////
                //UCZELNIA
                ////////////////////////////////////////////////////////////////////////////////////////////////
                else if (ConfigManager.ConfigManager.getConfiguration().Type == ConfigManager.Mode.University)
                {
                    /***************************************************************************************************************************************
                     * ********************************************** UCZELNIA UCZELNIE UCZELNIA ***********************************************************/
                    // Algorytm dla uczelni
                    //MessageBox.Show("ALgorytm dla uczelni!", "Algorytm dla uczelni");

                    //TODO pododawać wszystko dla algorytmu
                    int l_grup_przed = 0;
                    foreach (var sub in subjects)
                    {
                        l_grup_przed += sub.Count;
                    }

                    // Liczba przedmiotów które nie mogą odbywać się w tym samym czasie

                    Algorytm.Algorytm_Tworzenie_dla_Uczelni algUczelnia = new Algorytm.Algorytm_Tworzenie_dla_Uczelni(teachers.Count, subjects.Count, categories.Count, classrooms.Count, 5, 10);

                    /*
                    MessageBox.Show("Dane dla algorytmu: \n" +
                        "ilość przedmitów: " + subjects.Count + "\n" +
                        "ilość grup prze: " + l_grup_przed + "\n"
                        , "Algorytm dla uczelni");

                    */
                    // Dodawanie nauczyciela
                    // Dodanie nauczycieli do algorytmu szkoły
                    foreach (var _nauczyciel in teachers)
                    {
                        // Teraz przedmioty są zappisane gdzieindziej
                        int[] _subjects = new int[_nauczyciel.Subjects.Count];
                        //for (int i = 0; i < _nauczyciel.Subjects.Count; i++)
                        //{
                        //    _subjects[i] = _nauczyciel.Subjects.ElementAt(i).Id;
                        //}
                        for (int i = 0; i < _nauczyciel.SubjectCount.Count; i++)
                        {
                            _subjects[i] = _nauczyciel.SubjectCount.Keys.ElementAt(i).Id;
                        }


                        HourDAO hDao = DB.DAOFactory.getHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        IList<DB.Domain.Core.Hour> hours = _nauczyciel.Hours;
                        // przerobienie czasu na godziny kolejnych lekcji
                        ClassHourDAO classHourDAO = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        // Zamiana na przedziały
                        //IList<Algorytm_Przedzial> _przedzialy = new List<Algorytm_Przedzial>();

                        IList<Algorytm.Algorytm_Przedzial> _przedzialy = Converter.DomainConverter.getAlgorytm_Przedzial2(hours);
                        /*
                        foreach (var classHour in hours)
                        {
                            IList<Algorytm_Przedzial> _przedzialyGodzinowe = DomainConverter.getAlgorytm_Przedzial(classHour);
                            _przedzialy = _przedzialy.Concat<Algorytm_Przedzial>(_przedzialyGodzinowe).ToList<Algorytm_Przedzial>();
                            // DEBUG

                            //Console.WriteLine("nauczyciel: "+_nauczyciel.Id + " - " + classHour.Begin + " - " + classHour.End );
                        }
                         * */
                        // DEBUG
                        // wyświetlnie przedziałów
                        /*
                        Console.WriteLine("Nauczyciel: " + _nauczyciel.Id + ",przedmiotow: " + _nauczyciel.Subjects.Count + ",przedzialy: " + _przedzialy.Count);
                        foreach (var _p in _przedzialy)
                        {
                            Console.WriteLine("Przedzial - d:" + _p.Dzien + "(" + _p.Poczatek + "," + _p.Koniec + ")");
                        }
                        */

                        //Algorytm_Para_Studia algPara = new Algorytm_Para_Studia(
                        List<Algorytm.Algorytm_Para_Studia> prowPrzedmioty = new List<Algorytm.Algorytm_Para_Studia>();
                        //foreach( var sub in _nauczyciel.Subjects) {
                        //    //
                        //    //Algorytm_Para_Studia para = new Algorytm_Para_Studia( sub.Id, sub.Count);
                        //    Algorytm_Para_Studia para = new Algorytm_Para_Studia(sub.Id, 3);
                        //    prowPrzedmioty.Add( para);
                        //}

                        foreach (var sub in _nauczyciel.SubjectCount)
                        {
                            //
                            //Algorytm_Para_Studia para = new Algorytm_Para_Studia( sub.Id, sub.Count);
                            Algorytm.Algorytm_Para_Studia para = new Algorytm.Algorytm_Para_Studia(sub.Key.Id, sub.Value);
                            prowPrzedmioty.Add(para);
                        }

                        Algorytm.Algorytm_Nauczyciel nauczyciel = new Algorytm.Algorytm_Nauczyciel(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, prowPrzedmioty, _przedzialy.Count, _przedzialy.ToArray());

                        algUczelnia.Dodaj_nauczyciela(nauczyciel);
                        //algUczelnia.dodaj_nauczyciela(_nauczyciel.Id, 0, _nauczyciel.Subjects.Count, _subjects, _przedzialy.Count, _przedzialy.ToArray());
                    }
                    // Dodanie sal do algorytmu szkoły
                    foreach (var _sala in classrooms)
                    {
                        SubjectDAO subjectDAO = DB.DAOFactory.getSubjectDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        IList<DB.Domain.Core.Subject> _przedmioty = subjectDAO.getSubjectsByClassroom(_sala);

                        int[] _przedmiotyId = new int[_przedmioty.Count];
                        for (int i = 0; i < _przedmioty.Count; i++)
                        {
                            _przedmiotyId[i] = _przedmioty.ElementAt(i).Id;
                        }
                        ClassroomDAO classroomDao = DB.DAOFactory.getClassroomDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                        Algorytm.Algorytm_Sala sala = new Algorytm.Algorytm_Sala(_sala.Id, _przedmioty.Count, _przedmiotyId, true);


                        //algUczelnia.dodaj_sale(_sala.Id, _przedmioty.Count, _przedmiotyId);
                        algUczelnia.Dodaj_sale(sala);

                        // DEBUG
                        /*
                        for (int i = 0; i < _przedmioty.Count; i++)
                        {
                            Console.Write(_przedmiotyId[i] + " ");
                        }
                        Console.WriteLine(" Sala: " + _sala.Id + ", przedmiotow: " + _przedmioty.Count);
                        */
                    }

                    // Dodawanie przedmiotów
                    foreach (var przed in subjects)
                    {
                        Algorytm.Algorytm_Przedmiot przedmiot = new Algorytm.Algorytm_Przedmiot(przed.Id, przed.Count, przed.Time);
                        algUczelnia.Dodaj_przedmiot(przedmiot);
                        //algUczelnia.Dodaj_przedmiot(
                    }

                    // Dodanie nadgrup do przedmiotów

                    foreach (var cat in categories)
                    {
                        /*
                        List<int> idki = new List<int>();
                        foreach (var prze in cat.Subjects)
                        {
                            idki.Add(prze.Id);
                        }
                        */

                        List<Subject> subs = new List<Subject>(cat.Subjects);
                        List<int> idki = subs.ConvertAll<int>(x => x.Id);
                        //int[] _subjects = new int[cat.Subjects.Count];
                        //for (int i = 0; i < cat.Subjects.Count; i++)
                        //{
                        //    //_subjects[i] =
                        //    _subjects[i] = cat.Subjects.ElementAt(i).Id;
                        //}
                        //Algorytm_Grupa_Przedmiotow gr = new Algorytm_Grupa_Przedmiotow(cat.Id, _subjects.ToList);

                        //List<int> idki = ((List<Subject>)cat.Subjects).ConvertAll(x => x.Id);
                        Algorytm.Algorytm_Grupa_Przedmiotow gr = new Algorytm.Algorytm_Grupa_Przedmiotow(cat.Id, idki);

                        algUczelnia.Dodaj_Grupe_Przedmiotow(gr);
                    }

                    // Testowanie czy wszaystkie dane są poprawne

                    //start:karmimy starym planem
                    ScheduleDAO scheduleDAO = DB.DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    ClassHourDAO classHourDAO2 = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    scheduleDAO.getAll();

                    List<Algorytm.Algorytm_Element_wyniku> algorytm_element_wyniku = Converter.DomainConverter.getAlgorytmElementWyniku(scheduleDAO.getAll());
                    algUczelnia.Ustaw_obecny_plan(algorytm_element_wyniku);
                    //end:karmimy starym planem

                    //start:karmimy niedostepnoscia nauczyciela
                    foreach (var x in teacherInnaccessibility)
                    {
                        TeacherInaccessibility t = x.Value;
                        Algorytm.Algorytm_Przedzial algorytm_przedzial = new Algorytm.Algorytm_Przedzial();
                        TimeSpan begin = new TimeSpan(t.from.Hour, t.from.Minute, t.from.Millisecond);
                        TimeSpan end = new TimeSpan(t.to.Hour, t.to.Minute, t.to.Millisecond);
                        DB.Domain.HourUniversity hour = new DB.Domain.HourUniversity();
                        hour.Day = t.day;
                        hour.Begin = begin;
                        hour.End = end;
                        IList<Algorytm.Algorytm_Przedzial> algorytmPrzedzialList = Converter.DomainConverter.getAlgorytm_Przedzial(hour);
                        foreach (var a in algorytmPrzedzialList)
                        {
                            algUczelnia.dodaj_nieobecnosc_nauczyciela(t.teacher.Id, a);
                        }
                    }
                    //end:karmimy niedostepnoscia nauczyciela

                    //start:karmimy niedostepnoscia sal
                    foreach (var y in classroomInaccessibility)
                    {
                        ClassroomInaccessibility cr = y.Value;
                        Algorytm.Algorytm_Przedzial algorytm_przedzial = new Algorytm.Algorytm_Przedzial();
                        TimeSpan begin = new TimeSpan(cr.from.Hour, cr.from.Minute, cr.from.Millisecond);
                        TimeSpan end = new TimeSpan(cr.to.Hour, cr.to.Minute, cr.to.Millisecond);
                        DB.Domain.HourUniversity hour = new DB.Domain.HourUniversity();
                        hour.Day = cr.day;
                        hour.Begin = begin;
                        hour.End = end;
                        IList<Algorytm.Algorytm_Przedzial> algorytmPrzedzialList = Converter.DomainConverter.getAlgorytm_Przedzial(hour);
                        foreach (var a in algorytmPrzedzialList)
                        {
                            algUczelnia.dodaj_niedostepnosc_sali(cr.classroom.Id, a);
                        }
                    }
                    //end:karmimy niedostepnoscia nauczyciela


                    // Usuwanie starego planu gdy wszystko ok
                    //ScheduleDAO scheduleDAO = DB.DAOFactory.getScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                    //scheduleDAO.deleteAll();
                    // generowanie PLANU

                    algUczelnia.Generuj_plan_awaryjny();
                    Algorytm.Algorytm_Wyniki algWyniki = algUczelnia.Pobierz_Plan();
                    List<Algorytm.Algorytm_Element_wyniku> wynikiAlg = algWyniki.Pobierz_Plan_Awaryjny();

                    Console.WriteLine("ILOSC WYNIKOW START*******************************************************************************************" + wynikiAlg.Count);
                    foreach (var wynik in wynikiAlg)
                    {
                        Console.WriteLine(wynik.Dzien + " " + wynik.Godzina + " " + wynik.Klasa + " " + wynik.Nauczyciel + " " + wynik.Przedmiot);
                    }

                    Console.WriteLine("ILOSC WYNIKOW END*******************************************************************************************" + wynikiAlg.Count);

                    if (algWyniki.Czy_wszystko_poszlo_dobrze)
                    {
                        //usuwamy stary plan
                        deleteOldEmergencySchedule();

                        IList<EmergencySchedule> emergencySchedule = Converter.DomainConverter.getEmergencySchedule(wynikiAlg, this.emergencyScheduleWeek);
                        EmergencyScheduleDAO emergencyScheduleDAO = DB.DAOFactory.getEmergencyScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);

                        //save teacherInnaccessibility
                        TeacherUnavailabilityDAO teachersUnavailabilityDAO = DB.DAOFactory.getTeacherUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        foreach (var ti in teacherInnaccessibility)
                        {
                            DB.Domain.Core.TeacherUnavailability tiObject = ti.Value.getTeacherUnavailabilityObject();

                                teachersUnavailabilityDAO.saveOrUpdate(tiObject);

                        }
                        //save classroomInaccessibility
                        ClassroomUnavailabilityDAO classroomsUnavailabilityDAO = DB.DAOFactory.getClassroomUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
                        foreach (var ci in classroomInaccessibility)
                        {
                            DB.Domain.Core.ClassroomUnavailability ciObject = ci.Value.getClassroomUnavailabilityObject();
                            classroomsUnavailabilityDAO.saveOrUpdate(ciObject);
                        }
                        //save emergencySchedule
                        foreach (var es in emergencySchedule)
                        {
                            emergencyScheduleDAO.saveOrUpdate(es);
                        }

                        MessageBox.Show("Wygenerowano plan!");
                    }
                    else
                    {
                        MessageBox.Show("Plan nie został wygenerowany pomyślnie!");
                    }
                }
            }

            buttonClearInaccessibility_Click(null, null);
            Cursor = Cursors.Default;
            this.buttonAddClassroomInaccessibility.Enabled = true;
            this.buttonAddTeacherInaccessibility.Enabled = true;
            this.buttonClearInaccessibility.Enabled = true;
            this.buttonEmergencySchedule.Enabled = true;
        }
        private bool checkTeachersUnavailability()
        {
            TeacherUnavailabilityDAO teacherUnavailabilityDAO = DB.DAOFactory.getTeacherUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<DB.Domain.Core.TeacherUnavailability> teachersUnavailability = teacherUnavailabilityDAO.getAll();

            //zawezenie do daty
            foreach (var dbtu in teachersUnavailability)
            {
                DateTime dbtuDate = new DateTime(dbtu.Date);
                if (theSameWeek(dbtuDate, this.emergencyScheduleWeek))
                {
                    return false;

                }
            }
            return true;
        }

        private bool checkClassroomsUnavailability()
        {
            ClassroomUnavailabilityDAO classroorUnavailabilityDAO = DB.DAOFactory.getClassroomUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<DB.Domain.Core.ClassroomUnavailability> classroomsUnavailability = classroorUnavailabilityDAO.getAll();


            //zawezenie do daty
            foreach (var dbcu in classroomsUnavailability)
            {
                DateTime dbcuDate = new DateTime(dbcu.Date);
                if (theSameWeek(dbcuDate, this.emergencyScheduleWeek))
                {
                    return false;
                }
            }
            return true;
        }
        private class TeacherInaccessibility
        {
            static IList<DB.Domain.Core.ClassHour> classHours = null;
            TeacherUnavailability dbTeacherUnavailability;
            String gridString;
            public Teacher teacher;
            long date; 
            public DateTime from;
            public DateTime to;
            public string comboBox;
            public DB.Domain.Core.Day day;
            IList<DB.Domain.Core.ClassHour> hours;
            public DB.Domain.Core.ClassHour hourBegin;
            public DB.Domain.Core.ClassHour hourEnd;

            public TeacherInaccessibility(DB.Domain.Core.Teacher teacher_p, DateTime from_p, DateTime to_p, DB.Domain.Core.Day day_p, string comboBox_p)
            {
                this.teacher = teacher_p;
                this.from = from_p;
                this.date = from_p.Date.Ticks;
                this.to = to_p;
                this.comboBox = comboBox_p;
                this.day = day_p;
                this.dbTeacherUnavailability = null;
                fillClassHours();
            }

            public TeacherInaccessibility(TeacherUnavailability teacherUnavailability_p, string comboBox_p){
                this.dbTeacherUnavailability = teacherUnavailability_p;
                this.teacher = teacherUnavailability_p.Teacher;
                this.date = teacherUnavailability_p.Date;
                this.hourBegin = teacherUnavailability_p.Begin;
                this.hourEnd = teacherUnavailability_p.End;
                this.comboBox = comboBox_p;
                this.day = teacherUnavailability_p.Day;

                long fromTicks = this.date + this.hourBegin.Begin.Ticks;
                long toTicks = this.date + this.hourEnd.End.Ticks;
                this.from = new DateTime(fromTicks);
                this.to = new DateTime(toTicks);
                Console.WriteLine(this.from.ToString());
                Console.WriteLine(this.to.ToString());
            }

            public void setRepresentativeGridString(String gridString_p)
            {
                this.gridString = gridString_p;
            }

            public String getRepresentativeGridString()
            {
                return this.gridString;
            }
            private void fillClassHours()
            {
                if (TeacherInaccessibility.classHours == null)
                {
                    DB.CoreDAO.ClassHourDAO dao = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type); ;
                    classHours = dao.getAll();
                }

                this.hours = new List<DB.Domain.Core.ClassHour>();
                foreach (var classHour in TeacherInaccessibility.classHours)
                {
                    if (this.from.TimeOfDay <= classHour.End && this.to.TimeOfDay >= classHour.End)
                    {
                        this.hours.Add(classHour);
                        Console.WriteLine("ti hour added: " + classHour.Begin.ToString() + " - " + classHour.End.ToString()+ " teacher ID: "+this.teacher.Id + " teacher Name: "+teacher.Name );
                    }
                    else if (this.to.TimeOfDay >= classHour.Begin && classHour.Begin >= this.from.TimeOfDay)
                    {
                        this.hours.Add(classHour);
                        Console.WriteLine("ti hour added: " + classHour.Begin.ToString() + " - " + classHour.End.ToString() + " teacher ID: " + this.teacher.Id + " teacher Name: " + teacher.Name);
                    }
                }
                IEnumerable<DB.Domain.Core.ClassHour> query = classHours.OrderBy(hour => hour.Begin);
                this.hourBegin = query.First();
                Console.WriteLine("ti hour First: " + this.hourBegin.ToString());
                this.hourEnd = query.Last();
                Console.WriteLine("ti hour End: " + this.hourBegin.ToString());
            }
            public DB.Domain.Core.TeacherUnavailability getTeacherUnavailabilityObject()
            {
                DB.Domain.Core.TeacherUnavailability teacherUnavailability;
                if (ConfigManager.ConfigManager.getConfiguration().Type == ConfigManager.Mode.School)
                {
                    teacherUnavailability = new DB.Domain.TeacherUnavailabilitySchool();
                }
                else
                {
                    teacherUnavailability = new DB.Domain.TeacherUnavailabilityUniversity();

                }
                teacherUnavailability.Begin = this.hourBegin;
                teacherUnavailability.End = this.hourEnd;
                teacherUnavailability.Date = this.from.Date.Ticks;
                teacherUnavailability.Day = this.day;
                teacherUnavailability.Teacher = this.teacher;
                return teacherUnavailability;
            }
            public bool hasHour(ClassHour hour)
            {
                foreach (var classHour in this.hours)
                {
                    if (hour.Id == classHour.Id)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        private class ClassroomInaccessibility
        {
            static IList<DB.Domain.Core.ClassHour> classHours = null;
            public DB.Domain.Core.Classroom classroom;
            long date;
            string gridString;
            ClassroomUnavailability dbClassroomUnavailability;
            public DateTime from;
            public DateTime to;
            public string comboBox;
            public DB.Domain.Core.Day day;
            IList<DB.Domain.Core.ClassHour> hours;
            public DB.Domain.Core.ClassHour hourBegin;
            public DB.Domain.Core.ClassHour hourEnd;

            public ClassroomInaccessibility(DB.Domain.Core.Classroom classroom_p, DateTime from_p, DateTime to_p, DB.Domain.Core.Day day_p, string comboBox_p)
            {
                this.classroom = classroom_p;
                this.from = from_p;
                this.date = from.Date.Ticks;
                this.to = to_p;
                this.comboBox = comboBox_p;
                this.day = day_p;
                this.dbClassroomUnavailability = null;
                fillClassHours();
            }
            public ClassroomInaccessibility(ClassroomUnavailability classroomUnavailability_p, String comboBox_p)
            {
                this.dbClassroomUnavailability = classroomUnavailability_p;
                this.classroom = classroomUnavailability_p.Classroom;
                this.comboBox = comboBox_p;
                this.day = classroomUnavailability_p.Day;
                this.hourBegin = classroomUnavailability_p.Begin;
                this.hourEnd = classroomUnavailability_p.End;
                this.date = classroomUnavailability_p.Date;

                long fromTicks = this.date + this.hourBegin.Begin.Ticks;
                long toTicks = this.date + this.hourEnd.End.Ticks;
                this.from = new DateTime(fromTicks);
                this.to = new DateTime(toTicks);
                Console.WriteLine(this.from.ToString());
                Console.WriteLine(this.to.ToString());

            }

            public void setRepresentativeGridString(String gridString_p)
            {
                this.gridString = gridString_p;
            }

            public String getRepresentativeGridString()
            {
                return this.gridString;
            }

            private void fillClassHours()
            {
                if (ClassroomInaccessibility.classHours == null)
                {
                    DB.CoreDAO.ClassHourDAO dao = DB.DAOFactory.getClassHourDAO(ConfigManager.ConfigManager.getConfiguration().Type); ;
                    classHours = dao.getAll();
                }

                this.hours = new List<DB.Domain.Core.ClassHour>();
                foreach (var classHour in ClassroomInaccessibility.classHours)
                {
                    if (this.from.TimeOfDay <= classHour.End && this.to.TimeOfDay >= classHour.End)
                    {
                        this.hours.Add(classHour);
                        Console.WriteLine("ci hour added: " + classHour.Begin.ToString() + " - " + classHour.End.ToString());
                    }
                    else if (this.to.TimeOfDay >= classHour.Begin && classHour.Begin >= this.from.TimeOfDay)
                    {
                        this.hours.Add(classHour);
                        Console.WriteLine("ci hour added: " + classHour.Begin.ToString() + " - " + classHour.End.ToString());
                    }
                }
                IEnumerable<DB.Domain.Core.ClassHour> query = classHours.OrderBy(hour => hour.Begin);
                this.hourBegin = query.First();
                Console.WriteLine("ti hour First: " + this.hourBegin.ToString());
                this.hourEnd = query.Last();
                Console.WriteLine("ti hour End: " + this.hourBegin.ToString());
            }

            public DB.Domain.Core.ClassroomUnavailability getClassroomUnavailabilityObject()
            {
                DB.Domain.Core.ClassroomUnavailability classroomUnavailability;
                if (ConfigManager.ConfigManager.getConfiguration().Type == ConfigManager.Mode.School)
                {
                    classroomUnavailability = new DB.Domain.ClassroomUnavailabilitySchool();
                }
                else
                {
                    classroomUnavailability = new DB.Domain.ClassroomUnavailabilityUniversity();
                }
                classroomUnavailability.Begin = this.hourBegin;
                classroomUnavailability.End = this.hourEnd;
                classroomUnavailability.Date = this.from.Date.Ticks;
                classroomUnavailability.Day = this.day;
                classroomUnavailability.Classroom = this.classroom;
                return classroomUnavailability;
            }

            public bool hasHour(ClassHour hour)
            {
                foreach (var classHour in this.hours)
                {
                    if (hour.Id == classHour.Id)
                    {
                        return true;
                    }
                }
                return false;
            }
        }
        private void clearInaccessibilityData()
        {
            gridTeacherInaccessibility.Rows.Clear();
            dataGridViewClassroomInaccessibility.Rows.Clear();
            this.teacherInnaccessibility.Clear();
            this.classroomInaccessibility.Clear();
            this.boolEmergencyScheduleWeek = false;
        }

        private IList<TeacherUnavailability> getConstraintTeacherUnavailability(IList<TeacherUnavailability> list, DateTime constraintWeek)
        {
            IList<TeacherUnavailability> toReturn = new List<TeacherUnavailability>();
            foreach (var l in list)
            {
                DateTime dt = new DateTime(l.Date);
                if (dt.Year == constraintWeek.Year && theSameWeek(dt, constraintWeek))
                {
                    toReturn.Add(l);
                }
            }
            return toReturn;
        }
        private IList<ClassroomUnavailability> getConstraintClassroomUnavailability(IList<ClassroomUnavailability> list, DateTime constraintWeek)
        {
            IList<ClassroomUnavailability> toReturn = new List<ClassroomUnavailability>();
            foreach (var l in list)
            {
                DateTime dt = new DateTime(l.Date);
                if (dt.Year == constraintWeek.Year && theSameWeek(dt, constraintWeek))
                {
                    toReturn.Add(l);
                }
            }
            return toReturn;
        }

        private void loadClassroomInaccessibility()
        {
            ClassroomUnavailabilityDAO classroomUnavailabilityDAO = DAOFactory.getClassroomUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<ClassroomUnavailability> classroomUnavailability = getConstraintClassroomUnavailability(classroomUnavailabilityDAO.getAll(), this.emergencyScheduleWeek);
            this.toDeleteClassroomUnavailability = classroomUnavailability;
            this.classroomInaccessibility.Clear();
            foreach (var cu in classroomUnavailability)
            {
                int n = dataGridViewClassroomInaccessibility.Rows.Add();
                String comboBox = cu.Classroom.Id + " - " + cu.Classroom.Name;
                ClassroomInaccessibility ci = new ClassroomInaccessibility(cu, comboBox);
                dataGridViewClassroomInaccessibility.Rows[n].Cells[0].Value = comboBox;
                dataGridViewClassroomInaccessibility.Rows[n].Cells[1].Value = ci.from.ToString("dd-MM-yyyy HH:mm");
                dataGridViewClassroomInaccessibility.Rows[n].Cells[2].Value = ci.to.ToString("dd-MM-yyyy HH:mm");
                dataGridViewClassroomInaccessibility.AutoResizeColumns();
                dataGridViewClassroomInaccessibility.AutoResizeRows();
                this.classroomInaccessibility.Add(n, ci);
            }
        }

        private void loadTeacherInaccessibility()
        {
            TeacherUnavailabilityDAO teacherUnavailabilityDAO = DAOFactory.getTeacherUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<TeacherUnavailability> teacherUnavailability = getConstraintTeacherUnavailability(teacherUnavailabilityDAO.getAll(), this.emergencyScheduleWeek);
            this.toDeleteTeacherUnavailability = teacherUnavailability;
            this.teacherInnaccessibility.Clear();
            foreach (var tu in teacherUnavailability)
            {
                int n = gridTeacherInaccessibility.Rows.Add();
                String comboBox = tu.Teacher.Id + " - " + tu.Teacher.Name;
                TeacherInaccessibility ti = new TeacherInaccessibility(tu, comboBox);
                gridTeacherInaccessibility.Rows[n].Cells[0].Value = comboBox;
                gridTeacherInaccessibility.Rows[n].Cells[1].Value = ti.from.ToString("dd-MM-yyyy HH:mm");
                gridTeacherInaccessibility.Rows[n].Cells[2].Value = ti.to.ToString("dd-MM-yyyy HH:mm");
                gridTeacherInaccessibility.AutoResizeColumns();
                gridTeacherInaccessibility.AutoResizeRows();
                this.teacherInnaccessibility.Add(n, ti);
            }
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            this.clearInaccessibilityData();
            //setting week variable
            this.emergencyScheduleWeek = dateTimePickerWeek.Value;
            this.boolEmergencyScheduleWeek = true;
            loadClassroomInaccessibility();
            loadTeacherInaccessibility();
            //reloading Lists
        }

        private void buttonDeleteTeacherInaccessibility_Click(object sender, EventArgs e)
        {
            Int32 selectedRowCount =
                gridTeacherInaccessibility.Rows.GetRowCount(DataGridViewElementStates.Selected);
            if (selectedRowCount > 0)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();

                for (int i = 0; i < selectedRowCount; i++)
                {
                    int index = gridTeacherInaccessibility.SelectedRows[i].Index;
                    sb.Append("Row: ");
                    sb.Append(index.ToString());
                    sb.Append(Environment.NewLine);

                    String gridString = gridTeacherInaccessibility.Rows[index].Cells[0].Value.ToString()
                        + gridTeacherInaccessibility.Rows[index].Cells[1].Value.ToString()
                        + gridTeacherInaccessibility.Rows[index].Cells[2].Value.ToString();
                    foreach (var x in this.teacherInnaccessibility) {
                        if (gridString.Equals(x.Value.getRepresentativeGridString())) {
                            this.teacherInnaccessibility.Remove(x.Key);
                            break;
                        }
                    }
                    gridTeacherInaccessibility.Rows.RemoveAt(index);
                    //this.teacherInnaccessibility.Remove(index);
                }

                sb.Append("Total: " + selectedRowCount.ToString());
                Console.Out.WriteLine(sb);
            }
        }

        private void buttonDeleteClassroomInaccessibility_Click(object sender, EventArgs e)
        {
            Int32 selectedRowCount =
    dataGridViewClassroomInaccessibility.Rows.GetRowCount(DataGridViewElementStates.Selected);
            if (selectedRowCount > 0)
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();

                for (int i = 0; i < selectedRowCount; i++)
                {
                    int index = dataGridViewClassroomInaccessibility.SelectedRows[i].Index;
                    sb.Append("Row: ");
                    sb.Append(index.ToString());
                    sb.Append(Environment.NewLine);
                    String gridString = dataGridViewClassroomInaccessibility.Rows[index].Cells[0].Value.ToString()
    + dataGridViewClassroomInaccessibility.Rows[index].Cells[1].Value.ToString()
    + dataGridViewClassroomInaccessibility.Rows[index].Cells[2].Value.ToString();
                    foreach (var x in this.classroomInaccessibility) { 
                        if(gridString.Equals(x.Value.getRepresentativeGridString())){
                            this.classroomInaccessibility.Remove(x.Key);
                            break;
                        }
                    }
                    dataGridViewClassroomInaccessibility.Rows.RemoveAt(index);
                    //this.classroomInaccessibility.Remove(index);
                }

                sb.Append("Total: " + selectedRowCount.ToString());
                Console.Out.WriteLine(sb);
            }
        }

        private IList<EmergencySchedule> getConstraintEmergencySchedule(IList<EmergencySchedule> list, DateTime constraintWeek)
        {
            IList<EmergencySchedule> toReturn = new List<EmergencySchedule>();
            foreach (var l in list)
            {
                DateTime dt = new DateTime(l.Date);
                if (dt.Year == constraintWeek.Year && theSameWeek(dt, constraintWeek))
                {
                    toReturn.Add(l);
                }
            }
            return toReturn;
        }

        private void deleteOldEmergencySchedule()
        {
            //TeacherUnavailability
            TeacherUnavailabilityDAO teacherUnavailabilityDAO = DAOFactory.getTeacherUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<TeacherUnavailability> teacherUnavailabilities = getConstraintTeacherUnavailability(teacherUnavailabilityDAO.getAll(), this.emergencyScheduleWeek);

            //ClassroomUnavailability
            ClassroomUnavailabilityDAO classroomUnavailabilityDAO = DAOFactory.getClassroomUnavailabilityDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<ClassroomUnavailability> classroomUnavailability = getConstraintClassroomUnavailability(classroomUnavailabilityDAO.getAll(), this.emergencyScheduleWeek);

            //EmergencyScheduleDAO
            EmergencyScheduleDAO emergencyScheduleDAO = DAOFactory.getEmergencyScheduleDAO(ConfigManager.ConfigManager.getConfiguration().Type);
            IList<EmergencySchedule> emergencyList = getConstraintEmergencySchedule(emergencyScheduleDAO.getAll(), this.emergencyScheduleWeek);

            foreach (var t in teacherUnavailabilities)
            {
                teacherUnavailabilityDAO.delete(t);
            }
            foreach (var c in classroomUnavailability)
            {
                classroomUnavailabilityDAO.delete(c);
            }
            foreach (var es in emergencyList)
            {
                emergencyScheduleDAO.delete(es);
            }
        }
    }

}